﻿using pHMb.Spectrogram;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace LungSoundWizard.View
{
    /// <summary>
    /// Interaction logic for LiveSpectrogramView.xaml
    /// </summary>
    public partial class LiveSpectrogramView : UserControl
    {
        AudioProcessor _audioProcessor;

        public static readonly DependencyProperty IsRunningProperty;
        public bool IsRunning
        {
            get { return (bool)GetValue(IsRunningProperty); }
            set { SetValue(IsRunningProperty, value); }
        }
        
        public static readonly DependencyProperty IsRecordingProperty;
        public bool IsRecording
        {
            get { return (bool)GetValue(IsRecordingProperty); }
            set { SetValue(IsRecordingProperty, value); }
        }
        
        public static readonly DependencyProperty FilePathProperty;
        public string FilePath
        {
            get { return (string)GetValue(FilePathProperty); }
            set { SetValue(FilePathProperty, value); }
        }

        public static readonly DependencyProperty RecordedFilePathProperty;
        public string RecordedFilePath
        {
            get { return (string)GetValue(RecordedFilePathProperty); }
            set { SetValue(RecordedFilePathProperty, value); }
        }

        RelayCommand _saveSelectionsCommand;
        public ICommand SaveSelectionsCommand
        {
            get
            {
                if (_saveSelectionsCommand == null)
                {
                    _saveSelectionsCommand = new RelayCommand(p =>
                        {
                            _audioProcessor.SelectionHandler.SaveSelections();
                            MessageBox.Show("Selections saved successfully.", "Lung Sound Selections", MessageBoxButton.OK, MessageBoxImage.Information);
                        });
                }
                return _saveSelectionsCommand;
            }
        } 
        
        RelayCommand _autoNameCommand;
        public ICommand AutoNameCommand
        {
            get
            {
                if (_autoNameCommand == null)
                {
                    _autoNameCommand = new RelayCommand(p => _audioProcessor.SelectionHandler.AutoName());
                }
                return _autoNameCommand;
            }
        }

        RelayCommand _groupSelectionsCommand;
        public ICommand GroupSelectionsCommand
        {
            get
            {
                if (_groupSelectionsCommand == null)
                {
                    _groupSelectionsCommand = new RelayCommand(p =>
                        _audioProcessor.SelectionHandler.GroupSelections(((IList)p).Cast<SpectrogramPane.XSelection>().ToList()),
                        p => p != null && ((IList)p).Count > 1);
                }
                return _groupSelectionsCommand;
            }
        }

        RelayCommand _setNoiseCommand;
        public ICommand SetNoiseCommand
        {
            get
            {
                if (_setNoiseCommand == null)
                {
                    _setNoiseCommand = new RelayCommand(p =>
                        _audioProcessor.SelectionHandler.SetNoise(((IList)p).Cast<SpectrogramPane.XSelection>().ToList()),
                        p => p != null && ((IList)p).Count > 0);
                }
                return _setNoiseCommand;
            }
        }

        RelayCommand _renameSelectionCommand;
        public ICommand RenameSelectionCommand
        {
            get
            {
                if (_renameSelectionCommand == null)
                {
                    _renameSelectionCommand = new RelayCommand(p =>
                        _audioProcessor.SelectionHandler.RenameSelection((SpectrogramPane.XSelection)p), 
                        p => p != null);
                }
                return _renameSelectionCommand;
            }
        }


        RelayCommand _deleteSelectionCommand;
        public ICommand DeleteSelectionCommand
        {
            get
            {
                if (_deleteSelectionCommand == null)
                {
                    _deleteSelectionCommand = new RelayCommand(p =>
                        spectrogramPane1.SelectedXPoints.Remove((SpectrogramPane.XSelection)p),
                        p => p != null);
                }
                return _deleteSelectionCommand;
            }
        }

        public SpectrogramPane Spectrogram
        {
            get
            {
                return spectrogramPane1;
            }
        }

        public string CurrentFile { get; set; }

        static LiveSpectrogramView()
        {
            IsRunningProperty =
                DependencyProperty.Register("IsRunning", typeof(bool),
                typeof(LiveSpectrogramView), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(IsEnabled_Changed)));
            IsRecordingProperty =
                DependencyProperty.Register("IsRecording", typeof(bool),
                typeof(LiveSpectrogramView), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(IsRecording_Changed)));

            FilePathProperty =
                DependencyProperty.Register("FilePath", typeof(string),
                typeof(LiveSpectrogramView), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(FilePath_Changed)));

            RecordedFilePathProperty =
                DependencyProperty.Register("RecordedFilePath", typeof(string),
                typeof(LiveSpectrogramView), new FrameworkPropertyMetadata(null));
        }

        SpectrogramPane spectrogramPane1;
        public LiveSpectrogramView()
        {
            InitializeComponent();

            spectrogramPane1 = new SpectrogramPane();
            spectrogramPane1.Dock = System.Windows.Forms.DockStyle.Fill;
            spectrogramPane1.AxesColor = System.Drawing.Color.WhiteSmoke;
            spectrogramPane1.BackColor = System.Drawing.Color.DimGray;
            spectrogramPane1.Divisor = 130;
            spectrogramPane1.isGreyScale = false;
            spectrogramPane1.Padding = new System.Windows.Forms.Padding(0, 10, 0, 0);
            
            this.spectrogramPane1.ScaleGraph = false;


            spectPanel.Controls.Add(spectrogramPane1);
            spectPanel.Scroll += spectPanel_Scroll;
            spectPanel.AutoScroll = false;

            _audioProcessor = new AudioProcessor(this.spectrogramPane1);
            
        }

        void spectPanel_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e)
        {
            spectrogramPane1.ScrollVPWidth = spectPanel.Width;
            spectrogramPane1.ScrollHorizOffset = -spectPanel.DisplayRectangle.X;
            spectrogramPane1.UpdateOverlay();
        }

        public static void IsEnabled_Changed(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            LiveSpectrogramView src = source as LiveSpectrogramView;

            if ((bool)e.NewValue == true)
            {
                src.RunSpectrogram();
            }
            else
            {
                src.StopSpectrogram();
            }
        }

        public static void IsRecording_Changed(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            LiveSpectrogramView src = source as LiveSpectrogramView;

            if ((bool)e.NewValue == true)
            {
                src.StartRecording();
            }
            else
            {
                src.StopRecording();
            }
        }

        public static void FilePath_Changed(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            LiveSpectrogramView src = source as LiveSpectrogramView;

            string path = (string)e.NewValue;


            if (src.CurrentFile != path && File.Exists(path))
            {
                src.CurrentFile = path;

                src.LoadFile(path);
            }
        }

        public void StartRecording()
        {
            _audioProcessor.Reset();
            _audioProcessor.StartRecord();
        }

        public void StopRecording()
        {
            RecordedFilePath = _audioProcessor.StopRecord();
        }

        public void RunSpectrogram()
        {
            _audioProcessor.StartLive();
        }

        public void StopSpectrogram()
        {
            _audioProcessor.Stop();
        }

        public void UnloadFile()
        {
            _audioProcessor.UnloadWave();
        }

        public void LoadFile(string path)
        {
            UnloadFile();

            spectrogramPane1.Dock = System.Windows.Forms.DockStyle.Left;
            this.spectrogramPane1.ScaleGraph = true;
            spectrogramPane1.Width = 500;
            spectPanel.AutoScroll = true;

            _audioProcessor.LoadWave(path);
        }
    }
}
